﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


//Agregado para utilizar el DataTable.
using System.Data;

/// <summary>
/// Clase controladora de los requerimientos.
/// </summary>
public class CtrlRequerimientos
{
    private CtrlBDRequerimientos ctrlBDRequerimientos;
    private List<itemConflict> lItemConflict;

    /// <summary>
    ///  Estructura para los conflictos
    /// </summary>
    private struct itemConflict
    {
        public static int INSERTING = 1;
        public static int NEUTRAL = 0;
        public static int DELETING = -1;
        public static int MODIFYING = 2;

        public static int EXIST = 1;
        public static int DONTEXIST = 0;

        public int local;
        public int server;
        public Conflicts conflict;

        public itemConflict(int iLocal, int iServer)
        {
            local = iLocal;
            server = iServer;
            conflict = new Conflicts();
        }
    }

    System.IFormatProvider format = new System.Globalization.CultureInfo("es-ES", true);

    /// <summary>
    /// Constructor
    /// </summary>
	public CtrlRequerimientos()
	{
        ctrlBDRequerimientos = new CtrlBDRequerimientos();
	}

    //Ejecuta una operacion dependiendo de el parametro tipo operacion con el resto de parametros en requerimiento funcional.
    public int ejecutarOperacion(int id, String nombreRequerimiento, int iteracion, String descripcion, String justificacion, int fuente,
        DateTime fechaInicio, DateTime fechaFinal, String esfuerzo, int estado, int prioridad , String criterioAceptacion,
        DateTime fechaCambio, int fuenteCambio, String descripcionCambio, String tipoOperacion, int depenR, int depenM)
    {
        int codigoResultado = -1;

        
        RequerimientoFuncional requerimiento = new RequerimientoFuncional(id, nombreRequerimiento, iteracion, descripcion, justificacion, fuente, fechaInicio, fechaFinal, esfuerzo, estado, prioridad, criterioAceptacion, fechaCambio, fuenteCambio, descripcionCambio, depenR, depenM);

        switch (tipoOperacion)
        {
            case "insertar":
                codigoResultado = ctrlBDRequerimientos.insertarRequerimientoFuncional(requerimiento);
                break;

            case "modificar":
                codigoResultado = ctrlBDRequerimientos.modificarRequerimientoFuncional(requerimiento);
                break;

            case "eliminar":
                codigoResultado = ctrlBDRequerimientos.eliminarRequerimientoFuncional(requerimiento);
                break;

            case "nuevaVersion":
                codigoResultado = ctrlBDRequerimientos.newVersionRF(requerimiento);
                break;
        }

        return codigoResultado;
    }


    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Retorna los requerimientos con los que 'id' no tiene conflictos
    public DataTable sinConflictos(int id)
    {
        return ctrlBDRequerimientos.sinConflictos(id);
    }

    //Retorna los requerimientos con los que 'id' tiene conflictos
    public DataTable conConflictos(int id)
    {
        return ctrlBDRequerimientos.conConflictos(id);
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    //Obtiene un dataset con las prioridades (nombre y id)
    public DataSet obtenerPrioridades() 
    {

        return ctrlBDRequerimientos.obtenerPrioridades();

    }

    //Obtiene un dataset con los estados (nombre y id)
    public DataSet obtenerEstados()
    {

        return ctrlBDRequerimientos.obtenerEstados();

    }

    //Ejecuta una operacion dependiendo del parametro tipo operacion con el resto de parametros en requerimiento no funcional.
    public int ejecutarOperacion(int id, String nombreRequerimiento, String descripcion, DataTable modulos,
        DateTime fechaCambio, int idFuenteCambio, String descripcionCambio, String tipoOperacion, int idProyeto)
    {
        int codigoResultado = -1;

        RequerimientoNoFuncional requerimiento = new RequerimientoNoFuncional(id, nombreRequerimiento, descripcion, modulos,
            fechaCambio, idFuenteCambio, descripcionCambio, idProyeto);

        switch (tipoOperacion)
        {
            case "insertar":
                codigoResultado = ctrlBDRequerimientos.insertarRequerimientoNoFuncional(requerimiento);
                break;

            case "modificar":
                codigoResultado = ctrlBDRequerimientos.modificarRequerimientoNoFuncional(requerimiento);
                break;

            case "eliminar":
                codigoResultado = ctrlBDRequerimientos.eliminarRequerimientoNoFuncional(requerimiento);
                break;
            case "nuevaVersion":
                codigoResultado = ctrlBDRequerimientos.newVersionRNF(requerimiento);
                break;
        }

        return codigoResultado;
    }
    //Retorna un requerimiento funcional consultado a punta del id
    public RequerimientoFuncional consultaRequerimientoFuncional(int id)
    {
        RequerimientoFuncional requerimiento;
        DataSet requerimientoTemporal;

        requerimientoTemporal = ctrlBDRequerimientos.recuperarRF(id);

        DataRow row = requerimientoTemporal.Tables[0].Rows[0];
        DateTime inicio = (DateTime)(row["FechaInicio"]);
        DateTime final = (DateTime)(row["FechaFinal"]);

        int dependeR, dependeM;
        if (row["DependeDeR"].ToString() != "")
        {
            dependeR = Int32.Parse(row["DependeDeR"].ToString());
        }
        else
        {
            dependeR = -1;
        }
        if (row["DependeDeM"].ToString() != "")
        {
            dependeM = Int32.Parse(row["DependeDeM"].ToString());
        }
        else
        {
            dependeM = -1;
        }

        requerimiento = new RequerimientoFuncional(row["Nombre"].ToString(), Int32.Parse(row["Iteracion"].ToString()), row["Descripcion"].ToString(), row["Justificacion"].ToString(), Int32.Parse(row["Fuente"].ToString()), inicio, final, row["EsfuerzoEstimado"].ToString(), Int32.Parse(row["Estado"].ToString()), Int32.Parse(row["Prioridad"].ToString()), row["CriterioDeAceptacion"].ToString(), dependeR, dependeM);

        return requerimiento;
    }


    //Agrega un conflicto entre requerimientos
    public void addConflict(int iIdConflicted, String sReason)
    {
        itemConflict temp = new itemConflict();
        temp.conflict.iIdConflicted = iIdConflicted;
        temp.conflict.sReason = sReason;
        temp.local = itemConflict.INSERTING;
        temp.server = itemConflict.DONTEXIST;

        bool esta = false;

        for (int i = 0; i < lItemConflict.Count && !(esta); ++i)
        {
            if (lItemConflict[i].conflict.iIdConflicted == iIdConflicted)
            {
                esta = true;
                temp.local = itemConflict.MODIFYING;
                temp.server = lItemConflict[i].server;
                lItemConflict.RemoveAt(i);
            }
        }

        lItemConflict.Add(temp);
    }

    //Elimina un conflicto entre requerimientos
    public void deleteConflict(int iIdConflicted)
    {
        itemConflict temp = new itemConflict();
        temp.conflict.iIdConflicted = iIdConflicted;
        temp.local = itemConflict.DELETING;
        temp.server = itemConflict.EXIST;

        for (int i = 0; i < lItemConflict.Count; ++i)
        {
            if (lItemConflict[i].conflict.iIdConflicted == iIdConflicted)
            {
                lItemConflict.RemoveAt(i);

                if (lItemConflict[i].server == itemConflict.EXIST)
                {
                    lItemConflict.Add(temp);
                }
            }
        }
    }

    //Retorna un requerimiento no funcional consultado a punta del id
    public RequerimientoNoFuncional consultaRequerimientoNoFuncional(int id)
    {
        RequerimientoNoFuncional requerimiento = new RequerimientoNoFuncional();
        DataSet requerimientoTemporal;

        requerimientoTemporal = ctrlBDRequerimientos.recuperarRNF(id);

        DataRow row = requerimientoTemporal.Tables[0].Rows[0];

        requerimiento.crearRequerimientoNoFuncionalSV(Int32.Parse(row["Id"].ToString()), row["Nombre"].ToString(), row["Descripcion"].ToString());

        return requerimiento;
    }

    //Obtiene un dataset con los modulos (nombre y id)
    public DataSet obtenerModulos(int proyecto)
    {
        DataSet modulos;

        modulos = ctrlBDRequerimientos.obtenerModulos(proyecto);

        return modulos;
    }

    //Obtiene un dataset con los requerimientos (nombre y id)
    public DataSet obtenerRequerimientos(int idModulo)
    {
        DataSet requerimientos;

        requerimientos = ctrlBDRequerimientos.obtenerRequerimientos(idModulo);

        return requerimientos;
    }

    //Obtiene un dataset con los subRequerimientos de un Requerimiento (nombre y id)
    public DataSet obtenerSubrequerimientos(int requerimiento)
    {
        DataSet subrequerimientos;

        subrequerimientos = ctrlBDRequerimientos.obtenerSubrequerimientos(requerimiento);

        return subrequerimientos;
    }

    //Obtiene un dataset con los requerimientos no funcionales (nombre y id)
    public DataSet obtenerRequerimientosNoFuncionales(int p)
    {
        DataSet req;
        req = ctrlBDRequerimientos.obtenerRequerimientosNoFuncionales(p);

        return req;
    }
    
    //Agrega un Modulo a un proyecto
    public int agregarModulo(int idProyecto, string nombre)
    {
        return ctrlBDRequerimientos.agregarModulo(idProyecto, nombre);
    }

    //Elimina un Modulo de un Proyecto
    public int eliminarModulo(int idModulo)
    {
        return ctrlBDRequerimientos.eliminarModulo(idModulo);
    }
	
	    // Obtiene el historial de versiones de un determinado Requerimiento
    public DataSet getHistorialRF(int id) {
        return ctrlBDRequerimientos.getHistorialRF(id);
    }

    // Obtiene el historial de versiones de un determinado Requerimiento No Funcional
    public DataSet getHistorialRNF(int id)
    {
        return ctrlBDRequerimientos.getHistorialRNF(id);
    }
}
